Imports System
Imports System.Text
Imports System.Data
Imports System.Collections.Generic

Imports Framework

#Region "Enum: Primary Key Values"
'<CLSCompliant(True)> _
'Public Enum EItem
'    Huey = 1
'    Duey = 2
'    Louie = 3
'End Enum
#End Region

'Table-Row Class (Customisable half)
Partial Public Class CItem

#Region "Constants"
#End Region

#Region "Constructors (Public)"
    'Default Connection String
    Public Sub New()
        MyBase.New()
    End Sub
    
    'Alternative Connection String
    Public Sub New(ByVal dataSrc as CDataSrc)
        MyBase.New(dataSrc)
    End Sub
    
    'Hidden (UI code should use cache instead)
    Protected Friend Sub New([itemId] As Integer)
        MyBase.New([itemId])
    End Sub
    Protected Friend Sub New(ByVal dataSrc As CDataSrc, [itemId] As Integer)
        MyBase.New(dataSrc, [itemId])
    End Sub
    Protected Friend Sub New(ByVal dataSrc As CDataSrc, ByVal [itemId] As Integer, ByVal txOrNull As IDbTransaction)
        MyBase.New(dataSrc, [itemId], txOrNull)
    End Sub
#End Region

#Region "Default Values"
    Protected Overrides Sub InitValues_Custom()
        'm_sampleDateCreated = DateTime.Now
        'm_sampleSortOrder   = 0
        m_itemDateCreated = DateTime.Now
        m_itemEstimatedHours = 1
    End Sub
#End Region

#Region "Default Connection String"
    Protected Overrides Function DefaultDataSrc() As CDataSrc
        Return CDataSrc.Default
    End Function
#End Region

#Region "Properties - Relationships"    
    'Relationships - Foriegn Keys (e.g parent)
    Public ReadOnly Property CreatedBy() As CUser
        Get
            Return CUser.Cache.GetById(Me.ItemCreatedByUserId)
        End Get
    End Property
    Public ReadOnly Property AssignedTo1() As CUser
        Get
            Return CUser.Cache.GetById(Me.ItemAssignedToUserId)
        End Get
    End Property
    Public ReadOnly Property AssignedTo2() As CUser
        Get
            Return CUser.Cache.GetById(Me.ItemAssignedToUserId2)
        End Get
    End Property
    Public ReadOnly Property AssignedTo3() As CUser
        Get
            Return CUser.Cache.GetById(Me.ItemAssignedToUserId3)
        End Get
    End Property
    Public ReadOnly Property AssignedTo4() As CUser
        Get
            Return CUser.Cache.GetById(Me.ItemAssignedToUserId4)
        End Get
    End Property

    Public ReadOnly Property AssignedToNames As List(Of String)
        Get
            Dim list As New List(Of String)(3)
            If Not IsNothing(AssignedTo1) Then list.Add(AssignedTo1.UserName)
            If Not IsNothing(AssignedTo2) Then list.Add(AssignedTo2.UserName)
            If Not IsNothing(AssignedTo3) Then list.Add(AssignedTo3.UserName)
            If Not IsNothing(AssignedTo4) Then list.Add(AssignedTo4.UserName)
            Return list
        End Get
    End Property

    Public ReadOnly Property AssignedToEmails As List(Of String)
        Get
            Dim list As New List(Of String)(3)
            If Not IsNothing(AssignedTo1) AndAlso Not String.IsNullOrEmpty(AssignedTo1.UserEmail) Then list.Add(AssignedTo1.UserEmail)
            If Not IsNothing(AssignedTo2) AndAlso Not String.IsNullOrEmpty(AssignedTo2.UserEmail) Then list.Add(AssignedTo2.UserEmail)
            If Not IsNothing(AssignedTo3) AndAlso Not String.IsNullOrEmpty(AssignedTo3.UserEmail) Then list.Add(AssignedTo3.UserEmail)
            If Not IsNothing(AssignedTo4) AndAlso Not String.IsNullOrEmpty(AssignedTo4.UserEmail) Then list.Add(AssignedTo4.UserEmail)
            Return list
        End Get
    End Property


    Public ReadOnly Property AssignedToNames_ As String
        Get
            Return CUtilities.ListToString(AssignedToNames)
        End Get
    End Property

    Public ReadOnly Property [Status]() As CStatus
        Get
            Return CStatus.Cache.GetById(Me.ItemStatusId)
        End Get
    End Property
    Public ReadOnly Property [Priority]() As CPriority
        Get
            Return CPriority.Cache.GetById(Me.ItemPriorityId)
        End Get
    End Property
    Public ReadOnly Property [Category]() As CCategory
        Get
            Return CCategory.Cache.GetById(Me.ItemCategoryId)
        End Get
    End Property


    'Relationships - Collections (e.g. children)
    Public ReadOnly Property [Comments] As CCommentList
        Get
            Return CComment.Cache.GetByItemId(Me.ItemId)
        End Get
    End Property
    Protected Function Comments_(ByVal tx As IDbTransaction) As CCommentList   'Only used for cascade deletes
        With New CComment(DataSrc)
            Return .SelectByItemId(Me.ItemId, tx)
        End With
    End Function
    Public ReadOnly Property [Files] As CFileList
        Get
            Return CFile.Cache.GetByItemId(Me.ItemId)
        End Get
    End Property
    Protected Function Files_(ByVal tx As IDbTransaction) As CFileList   'Only used for cascade deletes
        With New CFile(DataSrc)
            Return .SelectByItemId(Me.ItemId, tx)
        End With
    End Function
    Public ReadOnly Property [Historys] As CHistoryList
        Get
            Return CHistory.Cache.GetByItemId(Me.ItemId)
        End Get
    End Property
    Protected Function Historys_(ByVal tx As IDbTransaction) As CHistoryList   'Only used for cascade deletes
        With New CHistory(DataSrc)
            Return .SelectByItemId(Me.ItemId, tx)
        End With
    End Function

    Public ReadOnly Property [LinksFromMe] As CLinkList
        Get
            Return CLink.Cache.GetByFromItemId(Me.ItemId)
        End Get
    End Property
    Protected Function LinksFromMe_(ByVal tx As IDbTransaction) As CLinkList   'Only used for cascade deletes
        With New CLink(DataSrc)
            Return .SelectByFromItemId(Me.ItemId, tx)
        End With
    End Function

    Public ReadOnly Property [LinksToMe] As CLinkList
        Get
            Return CLink.Cache.GetByToItemId(Me.ItemId)
        End Get
    End Property
    Protected Function LinksToMe_(ByVal tx As IDbTransaction) As CLinkList   'Only used for cascade deletes
        With New CLink(DataSrc)
            Return .SelectByToItemId(Me.ItemId, tx)
        End With
    End Function
#End Region

#Region "Properties - Customisation"
    'Derived/ReadOnly (e.g. xml classes, presentation logic)
    Public Function RelatedItems() As CItemList
        Dim fromLinks As CLinkList = LinksFromMe
        Dim toLinks As CLinkList = LinksToMe
        Dim related As New CItemList(fromLinks.Count + toLinks.Count)
        For Each i As CLink In fromLinks
            If Not related.Contains(i.To) Then related.Add(i.To)
        Next
        For Each i As CLink In toLinks
            If Not related.Contains(i.From) Then related.Add(i.From)
        Next
        Return related
    End Function
    Public ReadOnly Property ItemDescriptionShort As String
        Get
            Return CUtilities.Truncate(ItemDescription, 255)
        End Get
    End Property

    Public ReadOnly Property CategoryName() As String
        Get
            Return Category.CategoryName
        End Get
    End Property
    Public ReadOnly Property PriorityName() As String
        Get
            Return Priority.PriorityName
        End Get
    End Property
    Public ReadOnly Property StatusName() As String
        Get
            Return Status.StatusName
        End Get
    End Property
#End Region

#Region "Save/Delete Overrides"
    Public Overrides Sub Delete(ByVal txOrNull As IDbTransaction)
        'Use a transaction if none supplied
        If txOrNull Is Nothing Then
            BulkDelete(Me)
            Exit Sub
        End If

        'Cascade-Delete (all child collections)
        Me.Comments_(txOrNull).DeleteAll(txOrNull)
        Me.Files_(txOrNull).DeleteAll(txOrNull)
        Me.Historys_(txOrNull).DeleteAll(txOrNull)
        Me.LinksFromMe_(txOrNull).DeleteAll(txOrNull)
        Me.LinksToMe_(txOrNull).DeleteAll(txOrNull)

        'Normal Delete
        MyBase.Delete(txOrNull)
    End Sub
#End Region

#Region "Custom Database Queries"
    '(Not normally required for cached classes, use list class for searching etc)
    'For Stored Procs can use: MakeListTyped (matching schema), or DataSrc.ExecuteDataset (reports etc)
    'For Dynamic sql, can use: SelectSum, SelectDistinct, SelectCount, SelectWhere (inherited methods)
#End Region

#Region "Searching (Optional)"
    'For cached classes, custom seach logic resides in static methods on the list class
    ' e.g. CItem.Cache.Search("..")

    'See also the auto-generated methods based on indexes
    ' e.g. CItem.Cache.GetBy...
#End Region

#Region "Caching Details"
    'Cache Key
    Friend Shared CACHE_KEY As String = GetType(CItem).ToString 'TABLE_NAME

    'Cache data
    Private Shared Function LoadCache() As CItemList
        Return New CItem().SelectAll()
    End Function

    'Cache Timeout
    Private Shared Sub SetCache(ByVal value As CItemList)
        If Not IsNothing(value) Then value.Sort()
        CCache.Set(CACHE_KEY, value) 'Optional parameter can override timeout (otherwise uses config-settings, which default to 3hrs)
    End Sub

    'Helper Method
    Private Function CacheGetById(ByVal list As CItemList) As CItem
        Return list.GetById(Me.ItemId)
    End Function
#End Region

#Region "Cloning"
    Public Function Clone(ByVal target As CDataSrc, ByVal txOrNull As IDbTransaction) As CItem ', parentId As Integer) As CItem
        'Shallow copy: Copies the immediate record, excluding autogenerated Pks
        Dim copy As New CItem(Me, target)

        'Deep Copy - Child Entities: Cloned children must reference their cloned parent
        'copy.SampleParentId = parentId

        copy.Save(txOrNull)

        'Deep Copy - Parent Entities: Cloned parents also clone their child collections
        'Me.Children.Clone(target, txOrNull, copy.ItemId)

        Return copy
    End Function
#End Region

#Region "ToXml"
    Protected Overrides Sub ToXml_Custom(ByVal w As System.Xml.XmlWriter)
        'Store(w, "Example", Me.Example)
    End Sub
#End Region

End Class
